package com.test.security;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cas.CasAuthenticationException;
import org.apache.shiro.cas.CasToken;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.util.StringUtils;
import org.jasig.cas.client.authentication.AttributePrincipal;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.TicketValidationException;
import org.jasig.cas.client.validation.TicketValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ShiroDbRealm extends org.apache.shiro.cas.CasRealm {
	private static Logger log = LoggerFactory.getLogger(ShiroDbRealm.class);
	
	/**
	 * 设置权限信息
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Principal principal = (Principal) principals.getPrimaryPrincipal();
		if (principal == null) {
			return null;
		}
		SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
		// TODO:权限获取
		List<String> permissions = new ArrayList();
		permissions.add("...");
		simpleAuthorizationInfo.addStringPermissions(permissions);
		return simpleAuthorizationInfo;
	}


	/**
	 * 在原CasRealm方法上做调整
	 * @param token
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		CasToken casToken = (CasToken)token;
		if(token == null) {
			return null;
		} else {
			String ticket = (String)casToken.getCredentials();
			if(!StringUtils.hasText(ticket)) {
				return null;
			} else {
				TicketValidator ticketValidator = this.ensureTicketValidator();

				try {
					Assertion e = ticketValidator.validate(ticket, this.getCasService());
					AttributePrincipal casPrincipal = e.getPrincipal();
					String userId = casPrincipal.getName();
					log.debug("Validate ticket : {} in CAS server : {} to retrieve user : {}", new Object[]{ticket, this.getCasServerUrlPrefix(), userId});
					Map attributes = casPrincipal.getAttributes();
					casToken.setUserId(userId);
					String rememberMeAttributeName = this.getRememberMeAttributeName();
					String rememberMeStringValue = (String)attributes.get(rememberMeAttributeName);
					boolean isRemembered = rememberMeStringValue != null && Boolean.parseBoolean(rememberMeStringValue);
					if(isRemembered) {
						casToken.setRememberMe(true);
					}

					//List principals = CollectionUtils.asList(new Object[]{userId, attributes});
					//使用自定义的Principal
					Principal principals=new Principal("id", userId, "trueName", "email");
					SimplePrincipalCollection principalCollection = new SimplePrincipalCollection(principals, this.getName());
					return new SimpleAuthenticationInfo(principalCollection, ticket);
				} catch (TicketValidationException var14) {
					throw new CasAuthenticationException("Unable to validate ticket [" + ticket + "]", var14);
				}
			}
		}
	}
}
